#include "gtest/gtest.h"
#include "Carte.h"
#include "ColonneCartes.h"
#include "Solitaire.h"

class SolitaireTesteur: public ::testing::Test
{
public:
	Solitaire jeu;
};

TEST_F(SolitaireTesteur, Constructeurs)
{
	EXPECT_EQ(1, jeu.m_colonnes[0].reqListeCartes().taille());
	EXPECT_EQ(2, jeu.m_colonnes[1].reqListeCartes().taille());
	EXPECT_EQ(3, jeu.m_colonnes[2].reqListeCartes().taille());
	EXPECT_EQ(4, jeu.m_colonnes[3].reqListeCartes().taille());
	EXPECT_EQ(5, jeu.m_colonnes[4].reqListeCartes().taille());
	EXPECT_EQ(6, jeu.m_colonnes[5].reqListeCartes().taille());
	EXPECT_EQ(7, jeu.m_colonnes[6].reqListeCartes().taille());

	EXPECT_EQ(24, jeu.m_talon.taille());

	EXPECT_EQ(52,
			jeu.m_talon.taille() + jeu.m_colonnes[0].reqListeCartes().taille()
					+ jeu.m_colonnes[1].reqListeCartes().taille()
					+ jeu.m_colonnes[2].reqListeCartes().taille()
					+ jeu.m_colonnes[3].reqListeCartes().taille()
					+ jeu.m_colonnes[4].reqListeCartes().taille()
					+ jeu.m_colonnes[5].reqListeCartes().taille()
					+ jeu.m_colonnes[6].reqListeCartes().taille());
}

TEST_F(SolitaireTesteur, AvancerTalon)
{
	File<Carte> f;
	Carte c1, c2, c3, c4;

	c1.asgValeur(Carte::AS);
	c2.asgValeur(Carte::DEUX);
	c3.asgValeur(Carte::TROIS);
	c4.asgValeur(Carte::QUATRE);

	f.enfiler(c4);
	f.enfiler(c3);
	f.enfiler(c2);
	f.enfiler(c1);

	jeu.m_talon = f;

	EXPECT_EQ(c4.reqValeur(), jeu.m_talon.premier().reqValeur());
	jeu.avancerTalon();
	EXPECT_EQ(c3.reqValeur(), jeu.m_talon.premier().reqValeur());

	EXPECT_EQ(c3.reqValeur(), jeu.m_talon.premier().reqValeur());
	jeu.avancerTalon();
	EXPECT_EQ(c2.reqValeur(), jeu.m_talon.premier().reqValeur());

	EXPECT_EQ(c2.reqValeur(), jeu.m_talon.premier().reqValeur());
	jeu.avancerTalon();
	EXPECT_EQ(c1.reqValeur(), jeu.m_talon.premier().reqValeur());

	EXPECT_EQ(c1.reqValeur(), jeu.m_talon.premier().reqValeur());
	jeu.avancerTalon();
	EXPECT_EQ(c4.reqValeur(), jeu.m_talon.premier().reqValeur());
}

TEST_F(SolitaireTesteur, DeplacerColonneAColonne)
{
	Liste<Carte> l1, l2, l3;
	Carte c1, c2, c3;
	Carte b1, b2;

	c1.asgValeur(Carte::ROI);
	c1.asgSorte(Carte::PIQUE);
	c1.asgVisible(true);

	c2.asgValeur(Carte::REINE);
	c2.asgSorte(Carte::COEUR);
	c2.asgVisible(true);

	c3.asgValeur(Carte::VALET);
	c3.asgSorte(Carte::PIQUE);
	c3.asgVisible(true);

	l1.ajouter(c3, 1);
	l1.ajouter(c2, 1);
	l1.ajouter(c1, 1);

	b1.asgValeur(Carte::DIX);
	b1.asgSorte(Carte::CARREAU);
	b1.asgVisible(true);

	l2.ajouter(b1, 1);

	jeu.m_colonnes[0].initColonneCartes(l1);
	jeu.m_colonnes[1].initColonneCartes(l2);

	EXPECT_FALSE(jeu.m_colonnes[0].reqListeCartes().estVide());
	EXPECT_FALSE(jeu.m_colonnes[1].reqListeCartes().estVide());

	std::cout << jeu.m_colonnes[0] << std::endl;
	std::cout << jeu.m_colonnes[1] << std::endl;
	jeu.deplacerColonneAColonne(1, 0, 1);

	EXPECT_TRUE(jeu.m_colonnes[1].reqListeCartes().estVide());
	EXPECT_FALSE(jeu.m_colonnes[0].reqListeCartes().estVide());

	std::cout << jeu.m_colonnes[0] << std::endl;
	std::cout << jeu.m_colonnes[1] << std::endl;
	jeu.deplacerColonneAColonne(0, 1, 4);

	EXPECT_TRUE(jeu.m_colonnes[0].reqListeCartes().estVide());
	EXPECT_FALSE(jeu.m_colonnes[1].reqListeCartes().estVide());

	std::cout << jeu.m_colonnes[0] << std::endl;
	std::cout << jeu.m_colonnes[1] << std::endl;
}

TEST_F(SolitaireTesteur, DeplacerTalonAColonne)
{
	File<Carte> f;
	Carte c1, c2, c3, c4, c5;

	c1.asgValeur(Carte::REINE);
	c1.asgSorte(Carte::CARREAU);

	c2.asgValeur(Carte::AS);
	c2.asgSorte(Carte::PIQUE);

	c3.asgValeur(Carte::TROIS);
	c3.asgSorte(Carte::TREFLE);

	c4.asgValeur(Carte::QUATRE);
	c4.asgSorte(Carte::CARREAU);

	f.enfiler(c4);
	f.enfiler(c3);
	f.enfiler(c2);
	f.enfiler(c1);

	jeu.m_talon = f;

	Liste<Carte> l;
	Carte cc1;

	cc1.asgValeur(Carte::CINQ);
	cc1.asgSorte(Carte::PIQUE);
	l.ajouter(cc1, 1);

	jeu.m_colonnes[0].initColonneCartes(l);
	EXPECT_EQ(cc1.reqValeur(), jeu.m_colonnes[0].getDerniereCarte().reqValeur());

	jeu.deplacerTalonAColonne(0);
	EXPECT_EQ(c4.reqValeur(), jeu.m_colonnes[0].getDerniereCarte().reqValeur());
	EXPECT_EQ(c3.reqValeur(), jeu.m_talon.premier().reqValeur());

	jeu.deplacerTalonAColonne(0);
	EXPECT_EQ(c3.reqValeur(), jeu.m_colonnes[0].getDerniereCarte().reqValeur());

	EXPECT_THROW(jeu.deplacerTalonAColonne(0), std::runtime_error);
	jeu.avancerTalon();

	EXPECT_EQ(c1.reqValeur(), jeu.m_talon.premier().reqValeur());
	EXPECT_THROW(jeu.deplacerTalonAColonne(0), std::runtime_error);
}

TEST_F(SolitaireTesteur, DeplacerColonneAPile)
{
	Carte c1, c2, c3, c4;
	Liste<Carte> l1, l2, l3;

	c1.asgValeur(Carte::AS);
	c1.asgSorte(Carte::PIQUE);
	c2.asgValeur(Carte::DEUX);
	c2.asgSorte(Carte::PIQUE);
	l1.ajouter(c2, 1);
	l1.ajouter(c1, 2);
	jeu.m_colonnes[0].initColonneCartes(l1);

	c3.asgValeur(Carte::VALET);
	c3.asgSorte(Carte::COEUR);
	l2.ajouter(c3, 1);
	jeu.m_colonnes[1].initColonneCartes(l2);

	c4.asgValeur(Carte::AS);
	c4.asgSorte(Carte::COEUR);
	l3.ajouter(c4,1);
	jeu.m_colonnes[2].initColonneCartes(l3);

	EXPECT_TRUE(jeu.m_piles[Carte::PIQUE].estVide());
	jeu.deplacerColonneAPile(0);
	EXPECT_EQ(c1.reqValeur(), jeu.m_piles[Carte::PIQUE].top().reqValeur());

	jeu.deplacerColonneAPile(0);
	EXPECT_EQ(c2.reqValeur(), jeu.m_piles[Carte::PIQUE].top().reqValeur());

	EXPECT_TRUE(jeu.m_piles[Carte::COEUR].estVide());
	EXPECT_THROW(jeu.deplacerColonneAPile(1), std::runtime_error);

	jeu.deplacerColonneAPile(2);
	EXPECT_EQ(c4.reqValeur(), jeu.m_piles[Carte::COEUR].top().reqValeur());

	EXPECT_TRUE(!jeu.m_piles[Carte::COEUR].estVide());
	EXPECT_THROW(jeu.deplacerColonneAPile(1), std::runtime_error);
}

TEST_F(SolitaireTesteur, VerifieGagne)
{
	Pile<Carte> l;
	EXPECT_FALSE(jeu.verifieGagne());

	for(int i = 1; i <= 13; i++)
	{
		Carte c;
		l.empiler(c);
	}

	jeu.m_piles[0] = l;
	jeu.m_piles[1] = l;
	jeu.m_piles[2] = l;
	jeu.m_piles[3] = l;

	EXPECT_TRUE(jeu.verifieGagne());
}

